/************************************************************
* @file   gkt_flash.h
************************************************************/

#ifndef GKT_FLASH_H
#define GKT_FLASH_H

#include "gkt_types.h"

#ifdef __cplusplus
extern "C" {
#endif

/* on-chip flash memory */
#ifdef GKT_FLASH_ONCHIP_TYPE
#define GKT_FLASH_ONCHIP_PRESENT	1
#else
#define GKT_FLASH_ONCHIP_PRESENT	0
#endif

/* external flash memory */
#if defined(GKT_FLASH_EXTERNAL_TYPE) && GKT_CONFIG_FLASH_EXTERNAL_PRESENT
#define GKT_FLASH_EXTERNAL_PRESENT	1
#else
#define GKT_FLASH_EXTERNAL_PRESENT	0
#endif

#define GKT_FLASH_DEVICE_NUMS	\
	(GKT_FLASH_ONCHIP_PRESENT + GKT_FLASH_EXTERNAL_PRESENT)

/* permission */
#define GKT_FLASH_PERM_READABLE	(0x01 << 0)
#define GKT_FLASH_PERM_WRITABLE	(0x01 << 1)
#define GKT_FLASH_PERM_ERASABLE	(0x01 << 2)
#define GKT_FLASH_PERM_CHIP_ERASABLE	(0x01 << 3)
#define GKT_FLASH_PERM_MAPABLE	(0x01 << 8)

typedef struct _gkt_flash_info {
	uint32_t	page_size;
	uint32_t	sector_size;
	uint32_t	block_size;
	uint32_t	write_protect_unit_size;
	uint32_t	total_size;
	uint32_t	permission;
} gkt_flash_info_s;

int gkt_flash_init(void);

const gkt_flash_info_s *gkt_flash_get_info(uint32_t dev_id);

/*
 * @brief  map location <offset in region of the flash device> to
 *         an address that could be referred(read) directly if support
 * @params
 *	 dev_id    - [input] device id
 *	 offset    - [input] start location in region of flash device
 *   size      - [input] mapped space size
 * @return
 *   mapped address if success or NULL
 */
void *gkt_flash_map(uint32_t dev_id, uint32_t offset, 
			uint32_t size);

/*
 * @brief  flash read
 * @params
 *	 dev_id    - [input] device id
 *	 offset    - [input] read start location of flash device
 *	 size	   - [input] to read size, unit in bytes
 *	 buffer    - [input] read contents stores buffer
 * @return
 *	 > 0 : real read size, unit in bytes
 *	 < 0 : error occurs during reading operation
 */
int gkt_flash_read(uint32_t dev_id, 
			uint32_t offset, uint32_t size, 
			void *buffer);

/*
 * @brief  flash write
 * @params
 *	 dev_id    - [input] device id
 *	 offset    - [input] write start location of flash device
 *	 size	   - [input] to write size, unit in bytes
 *	 buffer    - [input] write source buffer
 * @return
 *	 0   : success
 *	 < 0 : error occurs during writing operation
 */
int gkt_flash_write(uint32_t dev_id, 
			uint32_t offset, uint32_t size, 
			const void *buffer);

/*
 * @brief  flash erase
 * @params
 *	 dev_id    - [input] device id
 *	 offset    - [input] start location of the flash device
 *	 size	   - [input] erase size, unit in bytes
 * @return
 *	 0   : success
 *	 < 0 : error occurs during erasing
 */
int gkt_flash_erase(uint32_t dev_id, 
			uint32_t offset, uint32_t size);

/*
 * @brief  flash chip erase
 * @params
 *	 dev_id    - [input] device id
 * @return
 *	 0   : success
 *	 < 0 : error occurs during erasing
 */
int gkt_flash_erase_chip(uint32_t dev_id);

/*
 * @brief flash write protect
 * @params
 *   dev_id   - [input] device id
 *   offset   - [input] start location of the flash device
 *   size     - [input] protect size, unit in bytes
 * @return
 *   0   : success
 *   < 0 : errors
 */
int gkt_flash_write_protect(uint32_t dev_id,
			uint32_t offset, uint32_t size);

#ifdef __cplusplus
}
#endif

#endif	/* GKT_FLASH_H */

